package com.all.proxy.handler;

import com.all.proxy.service.impl.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @Author LY
 * @create 2024/3/7 15:07
 * @Description 实现cglib动态代理
 */
@Slf4j
public class CglibProxyHandler<T> {

    private Object target;//代理目标类

    public CglibProxyHandler(){}

    public CglibProxyHandler(Object target) { //构造方法
        this.target = target;
    }

    private final Enhancer enhancer = new Enhancer();

    public <T> T getProxy(Class<T> clazz) {
        log.info("基于CGLib动态代理...");
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                log.info("cglib动态代理|{}|{}|{}|{}", o, method, objects,methodProxy);
                Object invoke = methodProxy.invokeSuper(o, objects);
                log.info("代理结束反参|{}", invoke);
                return invoke;
            }
        });
        return (T) enhancer.create();
    }

    public <T> T getProxyInterface(Class<T> clazz) {
        log.info("基于CGLib动态代理...");
        enhancer.setInterfaces(clazz.getInterfaces());
        enhancer.setCallback(new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                log.info("cglib动态代理|{}|{}|{}", proxy, method, args);
//                if (method.getReturnType() == String.class) {
//                    log.info("代理结束反参");
//                    return "Hello cglib";
//                }else {
                    Object invoke = method.invoke(target, args);// 使用proxy这里可能会出现无限循环，使用target则是调用目标方法
                    log.info("代理结束反参|{}", invoke);
                    return invoke;
//                }
            }
        });
        return (T) enhancer.create();
    }
}
